package org.springframework.aop.aspectj.annotation;

import org.aopalliance.intercept.MethodInterceptor;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.cglib.core.DebuggingClassWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurationSelector;

import java.util.List;

public class AopTest {

    @EnableTransactionManagement
    @Configuration
    static class Test {

    }
    private static final Logger log = LoggerFactory.getLogger(AopTest.class);

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/fengliulin/IdeaProjects/redis-learn-rabbit");

        GenericApplicationContext g = new GenericApplicationContext();
        g.registerBean("test", Test.class);
        g.registerBean("aspect1", Aspect1.class);
        g.registerBean("config", Config.class);
        g.registerBean("TransactionManagementConfigurationSelector", TransactionManagementConfigurationSelector.class);
        g.registerBean(ConfigurationClassPostProcessor.class);
        g.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        g.refresh();

//        for (String beanDefinitionName : g.getBeanDefinitionNames()) {
//            System.out.println(beanDefinitionName);
//        }


//        AnnotationAwareAspectJAutoProxyCreator bean = g.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
//        List<Advisor> t1 = bean.findCandidateAdvisors();
//
//        for (Advisor advisor : t1) {
//            System.out.println(advisor);
//        }
    }

    static class T1 {
        public void method1() {
            System.out.println("我是方法1");
        }

        public void method2() {
            System.out.println("我是方法2");
        }
    }

    @Aspect
    static class Aspect1 {
        public Aspect1() {
            System.out.println();
        }

        @Before("execution(* method1())")
        public void method1() {
            System.out.println("我是before");
        }
        @After("execution(* method1())")
        public void after() {
            System.out.println("我是after");
        }
    }

    @Configuration
    static class Config {
        @Bean
        public MethodInterceptor advisor31() {
            return invocation -> {
                System.out.println("before");
                Object proceed = invocation.proceed();
                System.out.println("after");
                return proceed;
            };
        }

        @Bean
        public Advisor advisor3() {
            AspectJExpressionPointcut a = new AspectJExpressionPointcut();
            a.setExpression("execution(* method1())");
            DefaultPointcutAdvisor d = new DefaultPointcutAdvisor(a, advisor31());


            return d;
        }


    }
}

